using UnityEngine;
using UnityEngine.UI;

namespace CGF
{
    public static class ScreenHelper
    {
        private static Canvas _canvas;
        private static Vector2 _screenSize;
        private static Vector2 _screenUISize;

        public static void InitScreenSize(Camera camera)
        {
            if (!camera.orthographic)
            {
                Debug.LogError($"InitScreenSize 仅支持传入正交摄影机！");
                return;
            }
            _screenSize.y = camera.orthographicSize * 2;
            _screenSize.x = _screenSize.y * camera.aspect;
        }

        public static void InitScreenUISize(Canvas canvas)
        {
            //这里先保存_canvas，后续第一次使用的时候再读取尺寸，否则在Awake里有时画布尺寸并没有准备好（已掉过坑）
            _canvas = canvas;
            _screenUISize = Vector2.zero;
        }

        /// <summary>
        /// 正交摄影机下的屏幕尺寸
        /// </summary>
        public static Vector2 screenSize
        {
            get
            {
                if (_screenSize == Vector2.zero)
                {
                    Debug.LogError("请在最早时间调用 ScreenHelper.InitScreenSize(camera) 获得屏幕场景尺寸");
                }
                return _screenSize;
            }
        }

        /// <summary>
        /// UI全屏尺寸
        /// </summary>
        public static Vector2 screenUISize
        {
            get
            {
                if (!_canvas)
                {
                    Debug.LogError("请在最早时间调用 ScreenHelper.InitScreenUISize(canvas) 获得屏幕UI尺寸");
                }
                else
                {
                    if (_screenUISize == Vector2.zero)
                    {
                        _screenUISize = (_canvas.transform as RectTransform).sizeDelta;
                    }
                }
                return _screenUISize;
            }
        }

        /// <summary>
        /// 世界转换到UGUI坐标
        /// </summary>
        public static Vector2 WorldToUGUIPoint(Vector3 worldPos, Canvas canvas)
        {
            Camera camera = canvas.renderMode == RenderMode.ScreenSpaceOverlay ? null : canvas.worldCamera;
            Vector2 screenPos = RectTransformUtility.WorldToScreenPoint(camera, worldPos);
            RectTransformUtility.ScreenPointToLocalPointInRectangle(canvas.transform as RectTransform, screenPos, camera, out Vector2 uiPos);
            return uiPos;
        }

        /// <summary>
        /// 屏幕转换到UGUI坐标
        /// </summary>
        public static Vector2 ScreenToUGUIPoint(Vector2 screenPos, Canvas canvas)
        {
            Camera camera = canvas.renderMode == RenderMode.ScreenSpaceOverlay ? null : canvas.worldCamera;
            RectTransformUtility.ScreenPointToLocalPointInRectangle(canvas.transform as RectTransform, screenPos, camera, out Vector2 uiPos);
            return uiPos;
        }

        /// <summary>
        /// UGUI转换到屏幕坐标
        /// </summary>
        public static Vector3 UGUIToScreenPoint(Vector2 uiPos)
        {
            Vector3 p;
            p.x = Screen.width * (uiPos.x + screenUISize.x * 0.5f) / screenUISize.x;
            p.y = Screen.height * (uiPos.y + screenUISize.y * 0.5f) / screenUISize.y;
            p.z = 0;
            return p;
        }

        /// <summary>
        /// 仅当全场没有摄影机，Canvas也不用摄影机时适用
        /// </summary>
        public static Vector3 WorldToScreenPoint(Vector3 worldPos)
        {
            return new Vector3(worldPos.x / screenUISize.x, worldPos.y / screenUISize.y, 0);
        }

        /// <summary>
        /// UGUI子物体锚点坐标转Canvas根坐标
        /// </summary>
        public static Vector2 LocalToRootPos(Vector2 uiPos, Transform parent)
        {
            CanvasScaler _canvasScaler = parent.GetComponent<CanvasScaler>();
            while (!_canvasScaler)
            {
                RectTransform parentTrans = parent as RectTransform;
                uiPos += parentTrans.anchoredPosition;
                if (parentTrans.anchorMin.x == 0 && parentTrans.anchorMax.x == 0)
                {
                    uiPos.x -= screenUISize.x * 0.5f;
                }
                else if (parentTrans.anchorMin.x == 1 && parentTrans.anchorMax.x == 1)
                {
                    uiPos.x += screenUISize.x * 0.5f;
                }
                //anchorMin.y和anchorMax.y变化时，不会影响锚点坐标，无需处理
                parent = parent.parent as RectTransform;
                _canvasScaler = parent.GetComponent<CanvasScaler>();
            }
            return uiPos;
        }
    }
}